Mybatis | 您所在的位置:网站首页 › mybatisplus limit语法 › Mybatis |
有道无术,术尚可求,有术无道,止于术。 文章目录 前言方案分析1. 分页2. XML自定义SQL 案例演示1. 配置2. 简单分页查询3. 带方言的分页查询 参考 前言在我们实际开发软件产品过程中,数据库的类型可能不是确定的,也有客户会有要求必须用什么数据库,比如很多政府机构要求必须使用国产数据库,所以我们在开发时,需要适配多种数据库。 MySQL、Oracle、PostgreSQL、达梦等数据库在进行增删改查时,都是基于美国国家标准局制定的SQL标准,比如SQL-92、SQL-99。 但是每个数据库厂商实际的SQL会有较小差异,也就是数据库方言,大家最熟知的就是MySQL分页使用limit,Oracle分页使用rownum。 MyBatis-Plus支持各种标准 SQL 的数据库,接下来我们实际演示如何使用MyBatis-Plus适配各种数据库。 很多数据库分页SQL使用方式都不大相同,MyBatis-Plus内置分页插件PaginationInnerInterceptor已支持多种数据库,官网说明: 在使用内置分页插件时,可以设置数据库的类型: @Configuration @MapperScan("com.pearl.pay.mapper") //持久层扫描 @EnableTransactionManagement //启用事务管理 public class MybatisPlusConfig { @Bean @ConditionalOnMissingBean(MybatisPlusInterceptor.class) public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); paginationInnerInterceptor.setDbType(DbType.MYSQL); interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; } }内置分页插件在执行SQL时,会根据当前数据库类型获取分页方言。 调用MP的API进行增删改查时,比如调用xxMpper.selectList()时,因为MP在构建SQL时,都是使用的基础标准,所以一般不存在兼容问题。但是我们自己在XML文件中编写SQL,就需要注意各种数据库匹配兼容问题了。 Mybatis本身已经做了多数据库支持,只需要告诉框架用的是什么数据库,可以根据不同的数据库厂商执行不同的语句。 Mybatis中的DatabaseIdProvider (数据库厂商标识提供者)接口声明了获取厂商标识的方法,标识可用于以后为每种数据库类型构建不同的查询,该机制支持多个厂商或版本。 public interface DatabaseIdProvider { default void setProperties(Properties p) { // NOP } // 根据数据源获取数据库厂商标识 String getDatabaseId(DataSource dataSource) throws SQLException; }Mybatis也提供了VendorDatabaseIdProvider实现类: public class VendorDatabaseIdProvider implements DatabaseIdProvider { // 支持的数据库厂商(需要自己定义),比如: Oracle=》oracle private Properties properties; // 获取数据库厂商标识ID(databaseId),eg:oracle @Override public String getDatabaseId(DataSource dataSource) { if (dataSource == null) { throw new NullPointerException("dataSource cannot be null"); } try { return getDatabaseName(dataSource); } catch (Exception e) { LogHolder.log.error("Could not get a databaseId from dataSource", e); } return null; } @Override public void setProperties(Properties p) { this.properties = p; } // 根据产品名称,获取对应的databaseId。 private String getDatabaseName(DataSource dataSource) throws SQLException { String productName = getDatabaseProductName(dataSource); if (this.properties != null) { for (Map.Entry property : properties.entrySet()) { if (productName.contains((String) property.getKey())) { return (String) property.getValue(); } } // no match, return null return null; } return productName; } // 从数据源中获取数据库产品名称,比如: Oracle private String getDatabaseProductName(DataSource dataSource) throws SQLException { try (Connection con = dataSource.getConnection()) { DatabaseMetaData metaData = con.getMetaData(); return metaData.getDatabaseProductName(); } } }在Mybatis的XML中编写SQL时,有个databaseId属性,可以指定当前语句块属于哪个数据库类型,比如: select * from user where user_id = #{id}综上:我们只需要配置DatabaseIdProvider 中支持哪些数据库,然后在XML中针对每种数据库方言编写查询语句,并添加databaseId属性,Mybatis会在启动时获取数据源使用的哪个类型数据库,然后执行配置了当前数据库对应的语句 案例演示 1. 配置搭建工程,集成MP、Oracle、Mysql很简单,这里就不赘述了。 在配置文件中,添加对应的Oracle、Mysql连接地址: spring: datasource: type: com.zaxxer.hikari.HikariDataSource driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@127.0.0.1:1521:ORCL username: root password: root #driver-class-name: com.mysql.cj.jdbc.Driver #url: jdbc:mysql://127.0.0.1:3306/d_account?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai #username: root #password: root在MP中添加配置类: @Configuration @MapperScan("com.pearl.pay.mapper") //持久层扫描 @EnableTransactionManagement //启用事务管理 public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(DataSource dataSource,DatabaseIdProvider databaseIdProvider) throws SQLException { // MP插件 MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); // 获取当前数据源对应的数据库类型,添加分页插件 String databaseId = databaseIdProvider.getDatabaseId(dataSource); DbType dbType = DbType.getDbType(databaseId); paginationInnerInterceptor.setDbType(dbType); interceptor.addInnerInterceptor(paginationInnerInterceptor); return interceptor; } @Bean public DatabaseIdProvider databaseIdProvider() { // 数据库厂商提供者 DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider(); Properties p = new Properties(); p.setProperty("Oracle", "oracle"); p.setProperty("Mysql", "mysql"); databaseIdProvider.setProperties(p); return databaseIdProvider; } } 2. 简单分页查询因为MyBatis-Plus内置分页插件已经做了适配,简单的(没有数据库方言)分页查询不用自己写代码适配。 首先添加一个分页查询: IPage test(Page page); select * from user数据源配置的是Oracle,没有配置databaseId,测试SQL语句打印如下: SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM ( select * from user) TMP WHERE ROWNUM 0数据源配置为Mysql,测试SQL语句打印如下: select * from user LIMIT 10 3. 带方言的分页查询需求: 查询时间节点小于当前时间的数据。 Oracle当前时间使用的是sysdate函数,Mysql使用的是now()函数,这个时候就需要手动去兼容了。 编写两个重名的查询语句,针对不同的数据库厂商编写SQL,并配置对应的databaseId select * from user t select * from user t也可以使用if语句,判断当前数据库类型,添加不同语句(推荐)。 select * from user t切换数据库,执行如下: select * from user t where t.create_time |
CopyRight 2018-2019 实验室设备网 版权所有 |